package article

import (
	"fmt"
	"net/http"
	model "server/model/article"
	"server/utils"
	"strings"

	"github.com/gin-gonic/gin"
)

var tableName = "article"

// CreateArticle 创建文章
func CreateArticle(c *gin.Context) {
	var req model.Article
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.JSONResponse(c, http.StatusBadRequest, fmt.Sprintf("请求格式或字段不合法: %v", err), nil)
		return
	}
	if !utils.ValidateStruct(c, &req) {
		return
	}
	if currentUserId, ok := c.Get("user_id"); ok {
		req.CreatorId = currentUserId.(int)
	} else {
		utils.JSONResponse(c, http.StatusUnauthorized, "身份验证失败！", nil)
		return
	}
	// 写入文章
	sqlStr := fmt.Sprintf("insert into %s (cate_id, tag_id, title, intro, content, cover_img, status, creator_id) values (?,?,?,?,?,?,?,?)", tableName)
	if _, err := utils.DB.Exec(sqlStr, req.CateId, req.TagId, req.Title, req.Intro, req.Content, req.CoverImg, req.Status, req.CreatorId); err != nil {
		utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("创建文章失败: %v", err), nil)
		return
	}
	utils.JSONResponse(c, http.StatusOK, "创建文章成功", nil)
}

// UpdateArticle 更新文章
func UpdateArticle(c *gin.Context) {
	var req model.Article
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.JSONResponse(c, http.StatusBadRequest, fmt.Sprintf("请求格式或字段不合法: %v", err), nil)
		return
	}
	if !utils.ValidateStruct(c, &req) {
		return
	}
	if currentUserId, ok := c.Get("user_id"); ok {
		req.UpdaterId = currentUserId.(int)
	} else {
		utils.JSONResponse(c, http.StatusUnauthorized, "身份验证失败！", nil)
		return
	}
	sqlStr := fmt.Sprintf("update %s set cate_id=?, tag_id=?, title=?, intro=?, content=?, cover_img=?, status=?, updater_id=? where id=?", tableName)
	if _, err := utils.DB.Exec(sqlStr, req.CateId, req.TagId, req.Title, req.Intro, req.Content, req.CoverImg, req.Status, req.UpdaterId, req.Id); err != nil {
		utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("更新文章信息失败: %v", err), nil)
		return
	}
	utils.JSONResponse(c, http.StatusOK, "更新文章信息成功", nil)
}

// DeleteArticle 删除文章
func DeleteArticle(c *gin.Context) {
	var req model.Article
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.JSONResponse(c, http.StatusBadRequest, fmt.Sprintf("请求格式或字段不合法: %v", err), nil)
		return
	}
	// 存在性校验
	if exists, err := utils.CheckTableExist(tableName, "id", req.Id); err != nil {
		utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("删除文章失败: %v", err), nil)
		return
	} else if !exists {
		utils.JSONResponse(c, http.StatusBadRequest, "文章不存在", nil)
		return
	}
	sqlStr := fmt.Sprintf("update %s set is_deleted=1 where id=?", tableName)
	if _, err := utils.DB.Exec(sqlStr, req.Id); err != nil {
		utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("删除文章失败: %v", err), nil)
		return
	}
	utils.JSONResponse(c, http.StatusOK, "删除文章成功", nil)
}

// RecoverArticle 恢复文章
func RecoverArticle(c *gin.Context) {
	var req model.Article
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.JSONResponse(c, http.StatusBadRequest, fmt.Sprintf("请求格式或字段不合法: %v", err), nil)
		return
	}
	if exists, err := utils.CheckTableExist(tableName, "id", req.Id); err != nil {
		utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("恢复文章失败: %v", err), nil)
		return
	} else if !exists {
		utils.JSONResponse(c, http.StatusBadRequest, "文章不存在", nil)
		return
	}
	sqlStr := fmt.Sprintf("update %s set is_deleted=0 where id=?", tableName)
	if _, err := utils.DB.Exec(sqlStr, req.Id); err != nil {
		utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("恢复文章失败: %v", err), nil)
		return
	}
	utils.JSONResponse(c, http.StatusOK, "恢复文章成功", nil)
}

// GetArticleDetail 获取文章详情
func GetArticleDetail(c *gin.Context) {
	var req model.Article
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.JSONResponse(c, http.StatusBadRequest, fmt.Sprintf("请求格式或字段不合法: %v", err), nil)
		return
	}
	if exists, err := utils.CheckTableExist(tableName, "id", req.Id); err != nil {
		utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("获取文章详情失败: %v", err), nil)
		return
	} else if !exists {
		utils.JSONResponse(c, http.StatusBadRequest, "文章不存在", nil)
		return
	}
	sqlStr := fmt.Sprintf(`
		SELECT 
			t.id, 
			t.cate_id, 
			t.tag_id, 
			t.title, 
			t.intro, 
			t.content, 
			t.cover_img, 
			t.views,
			t.status, 
			t.creator_id, 
			t.updater_id, 
			t.create_time, 
			t.update_time,
			t.is_deleted,
			uc.username AS creator,
			COALESCE(uu.username, '') AS updater,
			cn.name AS cate_name,
			tn.name AS tag_name
		FROM %s t
		LEFT JOIN user uc ON t.creator_id = uc.id
		LEFT JOIN user uu ON t.updater_id = uu.id
		LEFT JOIN article_cate cn ON t.cate_id = cn.id
		LEFT JOIN article_tag tn ON t.tag_id = tn.id
		WHERE t.id = ?
	`, tableName)
	var articleInfo model.ArticleDetail
	if err := utils.DB.QueryRow(sqlStr, req.Id).Scan(
		&articleInfo.Id,
		&articleInfo.CateId,
		&articleInfo.TagId,
		&articleInfo.Title,
		&articleInfo.Intro,
		&articleInfo.Content,
		&articleInfo.CoverImg,
		&articleInfo.Views,
		&articleInfo.Status,
		&articleInfo.CreatorId,
		&articleInfo.UpdaterId,
		&articleInfo.CreateTime,
		&articleInfo.UpdateTime,
		&articleInfo.IsDeleted,
		&articleInfo.Creator,
		&articleInfo.Updater,
		&articleInfo.CateName,
		&articleInfo.TagName,
	); err != nil {
		utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("获取文章详情失败: %v", err), nil)
		return
	}
	// 浏览量 +1（忽略错误）
	_, _ = utils.DB.Exec(fmt.Sprintf("UPDATE %s SET views = views + 1 WHERE id = ?", tableName), req.Id)
	utils.JSONResponse(c, http.StatusOK, "获取文章详情成功", articleInfo)
}

// GetArticleList 获取文章列表
func GetArticleList(c *gin.Context) {
	var req model.Query
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.JSONResponse(c, http.StatusBadRequest, fmt.Sprintf("请求格式或字段不合法: %v", err), nil)
		return
	}
	var (
		args       []interface{}
		conditions []string
		result     = model.List{}
	)
	if req.Keyword != "" {
		conditions = append(conditions, "(t.title LIKE ? OR t.intro LIKE ?)")
		args = append(args, "%"+req.Keyword+"%", "%"+req.Keyword+"%")
	}
	if req.CateId != nil {
		conditions = append(conditions, "t.cate_id = ?")
		args = append(args, *req.CateId)
	}
	if req.TagId != nil {
		conditions = append(conditions, "t.tag_id = ?")
		args = append(args, *req.TagId)
	}
	if req.Status != nil {
		conditions = append(conditions, "t.status = ?")
		args = append(args, *req.Status)
	} else {
		conditions = append(conditions, "t.status = 1")
	}
	if req.IsDeleted != nil {
		conditions = append(conditions, "t.is_deleted = ?")
		args = append(args, *req.IsDeleted)
	} else {
		conditions = append(conditions, "t.is_deleted = 0")
	}

	countSQL := fmt.Sprintf("SELECT COUNT(*) FROM %s t WHERE 1=1", tableName)
	if len(conditions) > 0 {
		countSQL += " AND " + strings.Join(conditions, " AND ")
	}
	if err := utils.DB.QueryRow(countSQL, args...).Scan(&result.Total); err != nil {
		utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("获取文章列表失败: %v", err), nil)
		return
	}

	pageNum := 1
	pageSize := 100
	if req.PageNum != nil && *req.PageNum > 0 {
		pageNum = *req.PageNum
	}
	if req.PageSize != nil && *req.PageSize > 0 {
		if *req.PageSize > 100 {
			pageSize = 100
		} else {
			pageSize = *req.PageSize
		}
	}
	offset := (pageNum - 1) * pageSize

	querySQL := fmt.Sprintf(`
		SELECT 
			t.id, 
			t.cate_id, 
			t.tag_id, 
			t.title, 
			t.intro, 
			t.cover_img, 
			t.views,
			t.status, 
			t.create_time, 
			t.creator_id, 
			t.update_time, 
			t.updater_id,
			t.is_deleted,
			uc.username AS creator,
			COALESCE(uu.username, '') AS updater,
			cn.name AS cate_name,
			tn.name AS tag_name
		FROM %s t
		LEFT JOIN user uc ON t.creator_id = uc.id
		LEFT JOIN user uu ON t.updater_id = uu.id
		LEFT JOIN article_cate cn ON t.cate_id = cn.id
		LEFT JOIN article_tag tn ON t.tag_id = tn.id
		WHERE 1=1
	`, tableName)
	if len(conditions) > 0 {
		querySQL += " AND " + strings.Join(conditions, " AND ")
	}
	querySQL += " ORDER BY t.id DESC"
	querySQL += " LIMIT ? OFFSET ?"
	args = append(args, pageSize, offset)

	rows, err := utils.DB.Query(querySQL, args...)
	if err != nil {
		utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("获取文章列表失败: %v", err), nil)
		return
	}
	defer rows.Close()

	var articles []model.ArticleDetail = []model.ArticleDetail{}
	for rows.Next() {
		var article model.ArticleDetail
		if err := rows.Scan(
			&article.Id,
			&article.CateId,
			&article.TagId,
			&article.Title,
			&article.Intro,
			&article.CoverImg,
			&article.Views,
			&article.Status,
			&article.CreateTime,
			&article.CreatorId,
			&article.UpdateTime,
			&article.UpdaterId,
			&article.IsDeleted,
			&article.Creator,
			&article.Updater,
			&article.CateName,
			&article.TagName,
		); err != nil {
			utils.JSONResponse(c, http.StatusInternalServerError, fmt.Sprintf("获取文章列表失败: %v", err), nil)
			return
		}
		articles = append(articles, article)
	}
	result.List = articles
	utils.JSONResponse(c, http.StatusOK, "获取文章列表成功", result)
}


